import { NextApiRequest, NextApiResponse } from 'next';
import { withIronSessionApiRoute } from 'iron-session/next';
import { Cookie } from 'next-cookie';

import { ISession } from '@/pages/api';
import { ironOptions } from '@/config';
import { prepareConnection } from '@/db';
import { UserAuth, User } from '@/db/entity';
import { setCookie } from '@/utils';

const login = async (req: NextApiRequest, res: NextApiResponse) => {
  const { phone = '', verify = '', identity_type = 'phone' } = req.body;
  const session: ISession = req.session;
  const cookies = Cookie.fromApiRoute(req, res);

  const db = await prepareConnection();
  const userAuthRepo = db.getRepository(UserAuth);

  // 说明验证码是正确的，然后在 user_auths 表中查找 identity_type 是否有记录
  if (String(session.verifyCode) === String(verify)) {
    const userAuth = await userAuthRepo.findOne(
      {
        identity_type,
        identifier: phone,
      },
      {
        relations: ['user'], // 写了 relations 的话会将 user 表中的数据也加进去
      }
    );

    // 如果 userAuth 存在的话，则证明是已注册过的用户
    if (userAuth) {
      handleLogin(userAuth, session, res, cookies);
      return;
    }

    // 否则则注册新用户
    handleRegistration(
      phone,
      identity_type,
      session,
      userAuthRepo,
      res,
      cookies
    );

    return;
  }

  res?.status(200).json({ code: -1, msg: '验证码错误' });
};

const handleLogin = async (
  userAuth: any,
  session: ISession,
  res: NextApiResponse,
  cookies: any
) => {
  // 已存在的用户
  const user = userAuth.user;
  const { id, nickname, avatar } = user;

  // 把数据存到 session 中
  session.userId = id;
  session.nickname = nickname;
  session.avatar = avatar;

  await session.save();

  // 设置 cookie
  setCookie(cookies, { id, nickname, avatar });

  res?.status(200).json({
    code: 200,
    msg: '登录成功',
    data: {
      userId: id,
      nickname,
      avatar,
    },
  });
};

const handleRegistration = async (
  phone = '',
  identity_type = 'phone',
  session: ISession,
  userAuthRepo: any,
  res: NextApiResponse,
  cookies: any
) => {
  const user = new User();
  user.nickname = `user_${Math.floor(Math.random() * 10000)}`;
  user.avatar = '/images/avatar.jpg';
  user.job = 'none';
  user.introduction = 'none';

  const userAuth = new UserAuth();
  userAuth.user = user; // many to one
  userAuth.identifier = phone;
  userAuth.identity_type = identity_type;
  userAuth.credential = session.verifyCode;

  // 这里只需要保存 userAuth 的数据，不需要保存 user 的，因为级联关系
  const resUserAuth = await userAuthRepo.save(userAuth);
  const {
    user: { id, nickname, avatar },
  } = resUserAuth;

  // 设置 cookie
  setCookie(cookies, { id, nickname, avatar });

  res?.status(200).json({
    code: 200,
    msg: '登录成功',
    data: {
      userId: id,
      nickname,
      avatar,
    },
  });
};

export default withIronSessionApiRoute(login, ironOptions);
